//
// Copyright (c) 2008, Tyler Hawkins
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Predia nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY HIPP SOFTWARE ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL HIPP SOFTWARE BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//  PredView.m
//  Predator Test
//
//  Created by Tyler Hawkins on 01/02/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#define NUMBER_OF_TROOPS 100
#define TROOP_WIDTH 20
#define REFRESH_TIME 0.015F
#import "PredView.h"
#import "Trooper.h"

@implementation PredView

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
	
		troops = [[NSMutableArray alloc] initWithCapacity:NUMBER_OF_TROOPS];
		[self generateTroops];
        animLoop = [NSTimer scheduledTimerWithTimeInterval: REFRESH_TIME target:self selector:@selector(changeAnimationState) userInfo:nil repeats:YES];
    
	}
    return self;
}

- (void)drawRect:(NSRect)rect {

    // Drawing Troops First
	CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
	CGContextSetShouldAntialias(ctx, NO);
	CGContextSetRGBFillColor(ctx, 1, 0, 0, 1);
	
	int i = 0;
	while (i < [troops count]){
	
		////////////////////////////////////////
		// This draws the troops' representation
		CGRect temp = [[troops objectAtIndex:i] representation];
		CGContextFillRect(ctx, temp);
	
		/////////////////////////////////	
		// This draws the troops' Vector
		CGContextSaveGState(ctx);
		CGContextSetRGBStrokeColor(ctx, 0, 1, 0, 1);
		CGContextSetLineWidth(ctx, 3);
		CGContextMoveToPoint(ctx, [[troops objectAtIndex:i] getCenter].x , [[troops objectAtIndex:i] getCenter].y ); 
		// Add line arc here?
		CGContextAddLineToPoint(ctx, [[troops objectAtIndex:i] terminatingPoint].x , [[troops objectAtIndex:i] terminatingPoint].y );
		CGContextStrokePath(ctx);
		CGContextRestoreGState(ctx);
		
		//////////////////////////////////
		// This draws the troops' health
		CGContextSaveGState(ctx);
		int health = [[troops objectAtIndex:i] health];
		
		if (health >= 60){
			CGContextSetRGBFillColor(ctx, 0, 1, 0, 1);
		} else if ((health < 60) && (health > 30)) {
			CGContextSetRGBFillColor(ctx, 0.6, 0.7, 0, 1);
		} else if (health < 30) {
			CGContextSetRGBFillColor(ctx, 0.5, 0.02, 0.02, 1);
		}
		
		int healthWidth = health / 5;
		
		CGRect healthRect = CGRectMake(([[troops objectAtIndex:i] getCenter].x - 10), ([[troops objectAtIndex:i] getCenter].y - 18),healthWidth, 5);
		//CGContextFillRect(ctx, healthRect);
		CGContextRestoreGState(ctx);
		
		/////////////////////////////////////
		// This draws a troop's visual range
		CGContextSaveGState(ctx);
		CGContextSetRGBFillColor(ctx, 0.25, 0.25, 1, 0.05f);
		CGContextAddPath(ctx, [[troops objectAtIndex:i] visableArea]);
		CGContextFillPath(ctx);
		CGContextRestoreGState(ctx);

		/////////////////////////////////////
		// This draws a troop's attack range
		CGContextSaveGState(ctx);
		CGContextSetRGBStrokeColor(ctx, 1, 0, 0, 0.25f);
		CGContextAddPath(ctx, [[troops objectAtIndex:i] attackableArea]);
		CGContextStrokePath(ctx);
		CGContextRestoreGState(ctx);
		
		//////////////////
		//DEBUG
		NSLog(@"%f, %f",[[troops objectAtIndex:1] getCenter].x, [[troops objectAtIndex:1] getCenter].y);
		NSLog(@"%f", ([[troops objectAtIndex:1] angle] * (180/pi)));
		//DEBUG
		//////////////////
		
		i++;
	}
}

- (void) generateTroops
{
	///////////////////
	// DEBUG GENERATOR
	
	int health1 = 0;
	
	CGPoint position1 = CGPointMake(200, 100);
	CGPoint position2 = CGPointMake(400, 100);
	
	float angle1 = pi;
	float angle2 = 0;
		
	Trooper * aTroop1 = [[Trooper alloc] initWithPosition:position1 
												   andHealth:health1 
													andAngle:angle2 
													andWIdth:TROOP_WIDTH
													andDelegate: self];

	[troops addObject: aTroop1];

	Trooper * aTroop2 = [[Trooper alloc] initWithPosition:position2
												   andHealth:health1 
													andAngle:angle1 
													andWIdth:TROOP_WIDTH
													andDelegate: self];

	[troops addObject: aTroop2];
	return;
	
	// DEBUG GENERATOR
	//////////////////////
	
	
	
	// A Troop:
	//		> A Position
	//		> A Health Score
	//		> A Vector
	
	NSDate * now = [NSDate date];	
	
	srand([now timeIntervalSinceReferenceDate]);
	
	int i = 0;
	while(i<NUMBER_OF_TROOPS){
		// A Position:
		
		int positionX = rand()%740;
		int positionY = rand()%385;
		
		CGPoint position = CGPointMake(positionX, positionY);

		// A Health Score:
		int health;
		health = rand()%35 + 65;

		// Calculate a point on the unit circle surrounding the center
		float angle = rand()%6 + 1;
		
		float offsetX = cos(angle), offsetY = sin(angle);
		offsetX *= 10; offsetY *= 10;

		Trooper * aTroop = [[Trooper alloc] initWithPosition:position 
												   andHealth:health 
													andAngle:angle 
													andWIdth:TROOP_WIDTH
													andDelegate: self];

		[troops addObject: aTroop];

		i++;
	}
	
	
}

- (void) mouseDown: (NSEvent *)event
{
	int index = 0;
	while (index < NUMBER_OF_TROOPS){
		int rnd = rand()%360 - 180;
		[[troops objectAtIndex: index] setAngle: [[troops objectAtIndex: index] angle] + rnd];
		index++;
	}
}

- (void) changeAnimationState{

	int i = 0;
	while(i < [troops count]){
	
		[[troops objectAtIndex:i] chooseBehavAction];
		i++;
	}	
	
	[self setNeedsDisplay:YES];

}

- (NSMutableArray *)troops
{
	return troops;
}

@end
